package com.demo.resourcecode.c11mvc.webAsyncTask;

import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.WebAsyncTask;

@Controller
@RequestMapping("/async")
public class WebAsyncTaskController {

	private static final Logger logger = LoggerFactory.getLogger(WebAsyncTaskController.class);

	@ResponseBody
    @GetMapping("/hello")
    public Callable<String> helloGet() throws Exception {
		logger.info("主线程start");

        Callable<String> callable = () -> {
        	logger.info("子子子线程start");
            TimeUnit.SECONDS.sleep(5); //模拟处理业务逻辑，话费了5秒钟
            logger.info("子子子线程end");

			// 这里稍微小细节一下：最终返回的不是Callable对象，而是它里面的内容
            return "hello world";
        };

        logger.info("主线程end");
        return callable;
    }

	@ResponseBody
    @GetMapping("/hello2")
    public WebAsyncTask<String> helloGet2() throws Exception {
		logger.info("主线程start");

        Callable<String> callable = () -> {
        	logger.info("子子子线程start");
            TimeUnit.SECONDS.sleep(2); //模拟处理业务逻辑，话费了5秒钟
            logger.info("子子子线程end");
            String s = null;
            //s.indexOf("1");

            return "hello world";
        };

        // 采用WebAsyncTask 返回 这样可以处理超时和错误 同时也可以指定使用的Excutor名称
        WebAsyncTask<String> webAsyncTask = new WebAsyncTask<>(30000000l, "asyncThreadPool", callable);
        // 注意：onCompletion表示完成，不管你是否超时、是否抛出异常，这个函数都会执行的
        webAsyncTask.onCompletion(() -> System.out.println("程序[正常执行]完成的回调"));

        // 这两个返回的内容，最终都会放进response里面去===========
        webAsyncTask.onTimeout(() -> "程序[超时]的回调");
        // 备注：这个是Spring5新增的
        // webAsyncTask.onError(() -> "程序[出现异常]的回调");


        logger.info("主线程end");
        return webAsyncTask;
    }

}
